package com.wy.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.digest.MD5;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wy.common.Constants;
import com.wy.common.R;
import com.wy.common.exception.ServiceException;
import com.wy.controller.dto.UserDTO;
import com.wy.controller.dto.UserPasswordDTO;
import com.wy.entity.Role;
import com.wy.entity.User;
import com.wy.service.IRoleService;
import com.wy.service.IUserService;
import com.wy.utils.*;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;


import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 作者：王昭贵
 * 日期：2023/1/5
 */
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
    @Autowired
    private IUserService userService;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 调用阿里云服务 发送手机短信验证码
     *
     * @param user
     * @return
     */
    @PostMapping("/sendMsg")
    public R<String> sendMsg(@RequestBody User user, HttpSession session) {
        //获取手机号
        String phone = user.getPhone();
        if (StringUtils.isNotEmpty(phone)) {
            //生成随机的4位验证码
            String code = ValidateCodeUtils.generateValidateCode(4).toString();
            log.info("code={}", code);
            //调用阿里云提供的短信服务API完成发送短信
            SMSUtils.sendMessage("pethospital", "SMS_276415878", phone, code);
            //将生成的验证码缓存到Redis中，并且设置有效期为5分钟
            redisTemplate.opsForValue().set(phone, code, 5, TimeUnit.MINUTES);
            return R.success("手机验证码短信发送成功");
        }
        return R.error(Constants.CODE_600, "发送验证码失败");
    }

    /****
     * 注册
     * @param userDTO
     * @return
     */
    @PostMapping("/register")
    public R<UserDTO> register(@RequestBody UserDTO userDTO) {
        String code = userDTO.getCode();
        String phone = userDTO.getPhone();
        Object codeInSession = redisTemplate.opsForValue().get(phone);
        if (codeInSession != null && codeInSession.equals(code)) {
            String password = DigestUtils.md5DigestAsHex(userDTO.getPassword().getBytes());
            User user = new User();
            user.setUsername(userDTO.getUsername());
            user.setPassword(password);
            user.setNickname(userDTO.getNickname());
            user.setRole("ROLE_DOCTOR");
            user.setStatus(1);
            user.setPhone(userDTO.getPhone());
            boolean save = userService.save(user);
            if (save) {
                redisTemplate.delete(phone);
                return R.success("注册成功");
            }
        }
        return R.error(Constants.CODE_603, "验证码错误");
    }

    /****
     * 登录接口
     * @param request
     * @param userDTO
     * @return
     */
    @ApiOperation(value = "用户登录", notes = "后台用户登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "string", paramType = "query", example = "wzg", required = true),
            @ApiImplicitParam(name = "password", value = "密码", dataType = "string", paramType = "query", example = "1234", required = true)
    })
    @PostMapping("/login")
    public R<UserDTO> login(HttpServletRequest request, @RequestBody UserDTO userDTO) {
        String codeUUID = userDTO.getCodeUUID();
        Object tpcode = redisTemplate.opsForValue().get(codeUUID);
        if(!tpcode.equals(userDTO.getCode())){
            return R.error(Constants.CODE_500,"验证码错误");
        }
        String username = userDTO.getUsername();
        String password = userDTO.getPassword();
        if (StrUtil.isBlank(username) || StrUtil.isBlank(password)) {
            return R.error(Constants.CODE_400, "用户名或密码不能为空");
        }
        UserDTO dto = userService.login(userDTO);
        redisTemplate.delete(codeUUID);
        return R.success("登录成功", dto);
    }


    /**
     * 根据id查询单个用户
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<User> getById(@PathVariable long id) {
        User user = userService.getById(id);
        return R.success(user);
    }

    @GetMapping("/role/{role}")
    public R findUsersByRole(@PathVariable String role) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role", role);
        List<User> list = userService.list(queryWrapper);
        return R.success(list);
    }

    /****
     * 前台首页获取医生列表 默认获取前4名医生
     * @return
     */
    @GetMapping("/getFrontDoctorList")
    public R getFrontDoctorList(){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getRole,"ROLE_DOCTOR");
        List<User> list = userService.list(lambdaQueryWrapper).subList(0,4);
        return R.success(list);

    }

    /**
     * 分页查询
     *
     * @param page
     * @param pageSize
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(int page, int pageSize, String username) {
        Page<User> pageInfo = new Page<>(page, pageSize);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(!StringUtils.isEmpty(username), User::getUsername, username);
        Page<User> page1 = userService.page(pageInfo, queryWrapper);
        User user = TokenUtils.getCurrentUser();
        if (user != null) {
            log.info(user.toString());
        }
        return R.success(pageInfo);
    }

    /****
     * 后台获取医生分页列表
     * @param page
     * @param pageSize
     * @param username
     * @return
     */
    @GetMapping("/doctorPage")
    public R<Page> doctorPage(int page, int pageSize, String username) {
        Page<User> pageInfo = new Page<>(page, pageSize);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(!StringUtils.isEmpty(username), User::getUsername, username);
        queryWrapper.eq(User::getRole, "ROLE_DOCTOR");
        Page<User> page1 = userService.page(pageInfo, queryWrapper);
        User user = TokenUtils.getCurrentUser();
        if (user != null) {
            log.info(user.toString());
        }
        return R.success(pageInfo);
    }

    /**
     * 删除用户
     *
     * @param id
     * @return
     */
    @DeleteMapping("{id}")
    public R<String> delete(@PathVariable Long id) {
        User user = userService.getById(id);
        user.setStatus(0);
        userService.updateById(user);
        return R.success("删除成功");
    }

    /**
     * 修改密码
     *
     * @param userPasswordDTO
     * @return
     */
    @PostMapping("/password")
    public R password(@RequestBody UserPasswordDTO userPasswordDTO) {
        LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUsername,userPasswordDTO.getUsername());
        User one = userService.getOne(lambdaQueryWrapper);
        String pass = DigestUtils.md5DigestAsHex(userPasswordDTO.getPassword().getBytes());
        if(!one.getPassword().equals(pass)){
            return R.error(Constants.CODE_500,"原密码错误");
        }
        one.setPassword(DigestUtils.md5DigestAsHex(userPasswordDTO.getNewPassword().getBytes()));
        boolean b = userService.updateById(one);
        if(!b){
            return R.error(Constants.CODE_500,"修改密码失败");
        }
        return R.success("修改密码成功");
    }

    /****
     * 根据用户名获取用户信息
     * @param username
     * @return
     */
    @GetMapping("/username/{username}")
    public R findByUsername(@PathVariable String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return R.success(userService.getOne(queryWrapper));
    }

    /**
     * 修改和新增
     *
     * @param user
     * @return
     */
    @PostMapping
    public R<String> updateOrInset(@RequestBody User user) {
        log.info(":::{}", user);
        user.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
        user.setStatus(1);
        boolean flag = userService.saveOrUpdate(user);
        if (flag) {
            return R.success("成功");
        }
        return R.success("失败");
    }
}



